package com.frejoys.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.frejoys.common.dto.admin.StoreIdAndNameDto;
import com.frejoys.common.dto.store.IdAndPageDto;
import com.frejoys.common.dto.store.StoreIdAndPageDto;
import com.frejoys.common.enums.*;
import com.frejoys.common.util.AppConfigUtil;
import com.frejoys.common.util.CommonUtil;
import com.frejoys.common.vo.admin.StoreWalletListVo;
import com.frejoys.common.vo.store.StoreWalletVo;
import com.frejoys.dao.entity.*;
import com.frejoys.dao.mapper.*;
import com.frejoys.service.OrderService;
import com.frejoys.service.StoreWalletService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class StoreWalletServiceImpl extends ServiceImpl<StoreWalletMapper, StoreWallet> implements StoreWalletService {

    private final OrderService orderService;

    private final OrderMapper orderMapper;

    private final StoreMapper storeMapper;

    private final UserMapper userMapper;

    private final StoreUserMapper storeUserMapper;

    private final StoreStatisticsYearMapper storeStatisticsYearMapper;
    @Override
    public void saveStoreWallet(Long orderSn, BigDecimal price, Integer payStatus) {
        Order order = orderService.getOnly(Wrappers.<Order>lambdaQuery().eq(Order::getOrderSn, orderSn));
        StoreWallet wallet = getOnly(Wrappers.<StoreWallet>lambdaQuery().eq(StoreWallet::getStoreId, order.getStoreId()));
        if (ObjectUtil.isEmpty(wallet)) {
            //新增一条
            wallet = new StoreWallet();
            wallet.setStoreId(order.getStoreId());
            if (payStatus.equals(EPayStatus.finish.getValue())) {
                wallet.setMoney(price);
            } else {
                wallet.setMoney(price.negate());
            }
        } else {
            if (payStatus.equals(EPayStatus.finish.getValue())) {
                wallet.setMoney(wallet.getMoney().add(price));
            } else {
                wallet.setMoney(wallet.getMoney().subtract(price));
            }
        }
        saveOrUpdate(wallet);
    }



    @Override
    public StoreWalletVo getStoreWalletInfo(IdAndPageDto dto) {

        if (dto.getId() == null){
            return new StoreWalletVo();
        }
        //查询店铺余额
        LambdaQueryWrapper<StoreWallet> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(StoreWallet::getMoney)
                .eq(StoreWallet::getStoreId,dto.getId());
        StoreWallet storeWallet = getOnly(wrapper);

        //查询店铺信息
        LambdaQueryWrapper<Store> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(Store::getName,Store::getLogo)
                .eq(Store::getId,dto.getId());
        Store store = storeMapper.selectOne(queryWrapper);

        //查询订单量
        Integer orderCount = orderMapper.orderCount(dto.getId(),EVerify.finish.getValue(), EStatus.on.getValue());

        //查询
        LambdaQueryWrapper<StoreStatisticsYear> yearWrapper = new LambdaQueryWrapper<>();
        yearWrapper.select(StoreStatisticsYear::getMoney).eq(StoreStatisticsYear::getStoreId,dto.getId());
        List<StoreStatisticsYear> storeStatisticsYears = storeStatisticsYearMapper.selectList(yearWrapper);

        BigDecimal moneyAll = BigDecimal.ZERO;
        if (!storeStatisticsYears.isEmpty()){
            for (StoreStatisticsYear s:storeStatisticsYears) {
                moneyAll = CommonUtil.bigDecimalAdd(moneyAll,s.getMoney());
            }
        }

        StoreWalletVo vo = new StoreWalletVo();
        if (ObjectUtil.isNotEmpty(storeWallet)){
            vo.setMoney(storeWallet.getMoney());
        }
        if (ObjectUtil.isNotEmpty(store)){
            vo.setName(store.getName());
            vo.setLogo(AppConfigUtil.getUrlPrefix(store.getLogo(), EFileSize.logo.getValue()));
        }

        vo.setOrderCount(orderCount);
        vo.setMoneyAll(moneyAll);

        return vo;
    }

    @Override
    public Map<Integer, BigDecimal> getStoreIdMoneyMap(List<Integer> storeIds) {
        LambdaQueryWrapper<StoreWallet> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(StoreWallet::getId,StoreWallet::getStoreId,StoreWallet::getMoney);
        wrapper.in(StoreWallet::getStoreId,storeIds);
        List<StoreWallet> list = baseMapper.selectList(wrapper);
        return list.stream().collect(Collectors.toMap(StoreWallet::getStoreId,StoreWallet::getMoney));
    }



    @Override
    public IPage<StoreWalletListVo> walletList(StoreIdAndNameDto dto) {
        Page page = new Page<>(dto.getPage(), dto.getSize());

        LambdaQueryWrapper<StoreWallet> wrapper = new LambdaQueryWrapper<>();
        if (dto.getStoreId() != null){
            wrapper.eq(StoreWallet::getStoreId,dto.getStoreId());
        }
        if (StrUtil.isNotEmpty(dto.getName())){
            List<Store> stores = storeMapper.getStoreNameById(dto.getName());

            if (stores.isEmpty()){
                return new Page<>();
            }

            List<Integer> storeIds = stores.stream().map(Store::getId).toList();
            wrapper.in(StoreWallet::getStoreId,storeIds);
        }
        if (StrUtil.isNotEmpty(dto.getTel())){
            List<Integer> storeIds = storeMapper.telByStoreId(dto.getTel());

            if (storeIds.isEmpty()){
                return new Page<>();
            }
            wrapper.in(StoreWallet::getStoreId,storeIds);
        }

        Page<StoreWallet> storeWalletPage = baseMapper.selectPage(page, wrapper);
        IPage<StoreWalletListVo> walletIPage = storeWalletPage.convert(storeWallet -> BeanUtil.copyProperties(storeWallet, StoreWalletListVo.class));
        List<StoreWalletListVo> walletList = walletIPage.getRecords();

        if (!walletList.isEmpty()){

            //取出店铺id
            List<Integer> storeIds = walletList.stream().map(StoreWalletListVo::getStoreId).toList();

            //查询店铺信息
            List<Store> stores = storeMapper.getStoreNameList(storeIds);
            Map<Integer, Store> storeMap = stores.stream().collect(Collectors.toMap(Store::getId, store -> store));

            //查询店铺拥有者id
            LambdaQueryWrapper<StoreUser> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.select(StoreUser::getUserId,StoreUser::getStoreId)
                    .in(StoreUser::getStoreId,storeIds)
                    .eq(StoreUser::getRole, EStoreUserRole.possess.getValue());
            List<StoreUser> storeUsers = storeUserMapper.selectList(queryWrapper);
            Map<Integer, Long> storeUserMap = storeUsers.stream().collect(Collectors.toMap(StoreUser::getStoreId, StoreUser::getUserId));

            //查询店铺拥有者信息
            List<Long> userIds = storeUsers.stream().map(StoreUser::getUserId).distinct().toList();
            List<User> users = userMapper.getUserByIds(userIds);
            Map<Long, User> userMap = users.stream().collect(Collectors.toMap(User::getId, user -> user));

            for (StoreWalletListVo vo:walletList) {

                if (storeMap.containsKey(vo.getStoreId())){
                    vo.setName(storeMap.get(vo.getStoreId()).getName());
                    vo.setTel(storeMap.get(vo.getStoreId()).getTel());
                    vo.setLogoUrl(AppConfigUtil.getUrlPrefix(storeMap.get(vo.getStoreId()).getLogo()));
                }

                if (storeUserMap.containsKey(vo.getStoreId())){

                    Long userId = storeUserMap.get(vo.getStoreId());

                    if (userMap.containsKey(userId)){

                        User user = userMap.get(userId);
                        vo.setNickname(user.getNickname());
                        vo.setPhone(user.getPhone());
                        vo.setAvatarUrl(AppConfigUtil.getUrlPrefix(user.getAvatar()));

                    }
                }
            }
        }
        return walletIPage;
    }
}
